
#include "TextureWindow.h"
#include "../signalslot.h"
#include <string>

#include "globals.h"

using namespace std;


TextureWindow::TextureWindow() : MyBaseWindow("Tex", 300, 500, BLUR_BEHIND),
								up_button_("^", -0.4f, 0.6f, 0.8f, 0.15f, window_size_),
								left_button_("<", -0.9f, 0.5f, 0.8f, 0.15f, window_size_),
								right_button_(">", 0.1f, 0.5f, 0.8f, 0.15f, window_size_),
								down_button_("v", -0.4f, 0.4f, 0.8f, 0.15f, window_size_),
								reset_button_("Reset", -0.2f, 0.3f, 0.4f, 0.1f, window_size_),
								ro_cw_button_("CW", -0.8f, 0.65f, 0.3f, 0.12f, window_size_),
								ro_ccw_button_("CCW", 0.5f, 0.65f, 0.3f, 0.12f, window_size_),
								scale_u_button_("<-->", -0.8f, 0.38f, 0.3f, 0.12f, window_size_),
								scale_u_button2_(">--<", -0.8f, 0.27f, 0.3f, 0.12f, window_size_),
								scale_v_button_("SV+", 0.5f, 0.38f, 0.3f, 0.12f, window_size_),
								scale_v_button2_("SV-", 0.5f, 0.27f, 0.3f, 0.12f, window_size_),
								choose_tex_btn_("Tex...", -0.2f, 0.0f, 0.4f, 0.1f, window_size_),
								//tex_params_layout_(-1.0f, -1.0f, 2.0f, 0.8f, window_size_, true),
								tex_params_layout_(true),
								tex_sm_angle_layout_(-1.0f, -1.0f, 2.0f, 0.8f, window_size_, false),
								tex_vec_u_layout_(-1.0f, -1.0f, 2.0f, 0.8f, window_size_, false),
								tex_vec_v_layout_(-1.0f, -1.0f, 2.0f, 0.8f, window_size_, false),
								sm_gr_edit_field_("Sm group", FLOATS),

								tex_vec00_edit_field_("u0: ", FLOATS),
								tex_vec01_edit_field_("u1: ", FLOATS),
								tex_vec02_edit_field_("u2: ", FLOATS),
								tex_vec03_edit_field_("u3: ", FLOATS),

								tex_vec10_edit_field_("v0: ", FLOATS),
								tex_vec11_edit_field_("v1: ", FLOATS),
								tex_vec12_edit_field_("v2: ", FLOATS),
								tex_vec13_edit_field_("v3: ", FLOATS),

								tex_angle_edit_field_("ang: ", FLOATS),

								tex_id_edit_field_("TexID: ", INTEGERS){

	//SetWindowPos(window_handle_, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
	//this->SetTopMost();

	shift_up_slot_.AssignFunction(this, &TextureWindow::ShiftTexUp);
	shift_up_slot_.Connect(up_button_.press_signal());

	shift_left_slot_.AssignFunction(this, &TextureWindow::ShiftTexLeft);
	shift_left_slot_.Connect(left_button_.press_signal());

	shift_right_slot_.AssignFunction(this, &TextureWindow::ShiftTexRight);
	shift_right_slot_.Connect(right_button_.press_signal());

	shift_down_slot_.AssignFunction(this, &TextureWindow::ShiftTexDown);
	shift_down_slot_.Connect(down_button_.press_signal());

	reset_slot_.AssignFunction(this, &TextureWindow::ResetTexture);
	reset_slot_.Connect(reset_button_.press_signal());

	ro_cw_slot_.AssignFunction(this, &TextureWindow::RotTexCW);
	ro_cw_slot_.Connect(ro_cw_button_.press_signal());

	ro_ccw_slot_.AssignFunction(this, &TextureWindow::RotTexCCW);
	ro_ccw_slot_.Connect(ro_ccw_button_.press_signal());

	scale_u_slot_.AssignFunction(this, &TextureWindow::ScaleUpU);
	scale_u_slot_.Connect(scale_u_button_.press_signal());
	scale_u_slot2_.AssignFunction(this, &TextureWindow::ScaleDownU);
	scale_u_slot2_.Connect(scale_u_button2_.press_signal());

	scale_v_slot_.AssignFunction(this, &TextureWindow::ScaleUpV);
	scale_v_slot_.Connect(scale_v_button_.press_signal());
	scale_v_slot2_.AssignFunction(this, &TextureWindow::ScaleDownV);
	scale_v_slot2_.Connect(scale_v_button2_.press_signal());

	choose_tex_slot_.AssignFunction(this, &TextureWindow::ChooseTexture);
	choose_tex_slot_.Connect(choose_tex_btn_.press_signal());

	sel_changed_slot_.AssignFunction(this, &TextureWindow::OnSelectionChange);
	sel_changed_slot_.Connect(g_selection_frame->sel_changed_signal);

	apply_sm_group_slot_.AssignFunction(this, &TextureWindow::ApplyTextureChange);
	apply_tex_vecs_.AssignFunction(this, &TextureWindow::ApplyTexVecs);
	apply_sm_group_slot_.Connect(sm_gr_edit_field_.changed_signal);
	apply_tex_angle_slot_.AssignFunction(this, &TextureWindow::ApplyTexAngle);

	apply_tex_vecs_.Connect(tex_vec00_edit_field_.changed_signal);
		apply_tex_vecs_.Connect(tex_vec01_edit_field_.changed_signal);
			apply_tex_vecs_.Connect(tex_vec02_edit_field_.changed_signal);
				apply_tex_vecs_.Connect(tex_vec03_edit_field_.changed_signal);
	tex_vec_u_layout_.AddElement(&tex_vec00_edit_field_);
	tex_vec_u_layout_.AddElement(&tex_vec01_edit_field_);
	tex_vec_u_layout_.AddElement(&tex_vec02_edit_field_);
	tex_vec_u_layout_.AddElement(&tex_vec03_edit_field_);

	apply_tex_vecs_.Connect(tex_vec10_edit_field_.changed_signal);
		apply_tex_vecs_.Connect(tex_vec11_edit_field_.changed_signal);
			apply_tex_vecs_.Connect(tex_vec12_edit_field_.changed_signal);
				apply_tex_vecs_.Connect(tex_vec13_edit_field_.changed_signal);
	tex_vec_v_layout_.AddElement(&tex_vec10_edit_field_);
	tex_vec_v_layout_.AddElement(&tex_vec11_edit_field_);
	tex_vec_v_layout_.AddElement(&tex_vec12_edit_field_);
	tex_vec_v_layout_.AddElement(&tex_vec13_edit_field_);

	apply_tex_angle_slot_.Connect(tex_angle_edit_field_.changed_signal);

	tex_sm_angle_layout_.AddElement(&sm_gr_edit_field_);
	tex_sm_angle_layout_.AddElement(&tex_id_edit_field_);
	tex_sm_angle_layout_.AddElement(&tex_angle_edit_field_);

	tex_params_layout_.AddElement(&tex_sm_angle_layout_);
	tex_params_layout_.AddElement(&tex_vec_u_layout_);
	tex_params_layout_.AddElement(&tex_vec_v_layout_);



	update_needed_ = true;
	OnMove(0.0f, 0.0f);
	tex_params_layout_.Resize(-0.95f, -0.95f, 1.9f, 0.5f, window_size_);
}

TextureWindow::~TextureWindow() {


}

int TextureWindow::OnClick(float x, float y) {
	if(MyBaseWindow::OnClick(x, y) == -1)
	{
		return -1;
	}

	up_button_.Check(x, y);
	left_button_.Check(x, y);
	right_button_.Check(x, y);
	down_button_.Check(x, y);

	reset_button_.Check(x, y);

	ro_cw_button_.Check(x, y);
	ro_ccw_button_.Check(x, y);

	scale_u_button_.Check(x, y);
	scale_u_button2_.Check(x, y);
	scale_v_button_.Check(x, y);
	scale_v_button2_.Check(x, y);

	choose_tex_btn_.Check(x, y);

	tex_params_layout_.Check(x, y);

	return 0;
}
/*
int TextureWindow::OnMove(float dx, float dy) {

	if(MyBaseWindow::OnMove(dx, dy) == -1)
	{
		return -1;
	}

	if(update_needed_)
	{

	}

}
*/

int TextureWindow::OnRelease(float x, float y) {
	if(MyBaseWindow::OnRelease(x, y) == -1)
	{
		return -1;
	}

	up_button_.Check(x, y);
	left_button_.Check(x, y);
	right_button_.Check(x, y);
	down_button_.Check(x, y);

	reset_button_.Check(x, y);

	ro_cw_button_.Check(x, y);
	ro_ccw_button_.Check(x, y);

	scale_u_button_.Check(x, y);
	scale_u_button2_.Check(x, y);
	scale_v_button_.Check(x, y);
	scale_v_button2_.Check(x, y);

	choose_tex_btn_.Check(x, y);

	tex_params_layout_.Check(x, y);

	return 0;
}

int TextureWindow::OnKeyPress(std::vector< unsigned char >& keys)
{
	sm_gr_edit_field_.Listen(keys);
	tex_id_edit_field_.Listen(keys);
	tex_angle_edit_field_.Listen(keys);

	tex_vec00_edit_field_.Listen(keys);
		tex_vec01_edit_field_.Listen(keys);
			tex_vec02_edit_field_.Listen(keys);
				tex_vec03_edit_field_.Listen(keys);
	tex_vec10_edit_field_.Listen(keys);
		tex_vec11_edit_field_.Listen(keys);
			tex_vec12_edit_field_.Listen(keys);
				tex_vec13_edit_field_.Listen(keys);

	return 0;
}

void TextureWindow::Draw()
{
	MyBaseWindow::Draw();
	this->SetTopMost();

	up_button_.Draw();
	left_button_.Draw();
	right_button_.Draw();
	down_button_.Draw();

	reset_button_.Draw();

	ro_cw_button_.Draw();
	ro_ccw_button_.Draw();

	scale_u_button_.Draw();
	scale_u_button2_.Draw();
	scale_v_button_.Draw();
	scale_v_button2_.Draw();

	choose_tex_btn_.Draw();

	tex_params_layout_.Draw();
}

int TextureWindow::ShiftTexUp() {
	float v[2] = { 0.0f, -(float)g_render_state.grid_size };
	g_selection_frame->ShiftTexture(v);
	return 0;
}
int TextureWindow::ShiftTexLeft() {
	float v[2] = { (float)g_render_state.grid_size, 0.0f };
	g_selection_frame->ShiftTexture(v);
	return 0;
}
int TextureWindow::ShiftTexRight() {
	float v[2] = { -(float)g_render_state.grid_size, 0.0f };
	g_selection_frame->ShiftTexture(v);
	return 0;
}
int TextureWindow::ShiftTexDown() {
	float v[2] = { 0.0f, (float)g_render_state.grid_size };
	g_selection_frame->ShiftTexture(v);
	return 0;
}
int TextureWindow::RotTexCW() {
	float angle = (180.0f/72.0f)*(g_render_state.grid_size/4);
	g_selection_frame->RotateTexture(angle);
	return 0;
}
int TextureWindow::RotTexCCW() {
	float angle = -(180.0f/72.0f)*(g_render_state.grid_size/4);
	g_selection_frame->RotateTexture(angle);
	return 0;
}
int TextureWindow::ScaleUpU() {
	g_selection_frame->ScaleTexture(0.9f);
	return 0;
}
int TextureWindow::ScaleDownU() {
	g_selection_frame->ScaleTexture(1.1f);
	return 0;
}
int TextureWindow::ScaleUpV() {
	g_selection_frame->ScaleTexture(-0.9f);
	return 0;
}
int TextureWindow::ScaleDownV() {
	g_selection_frame->ScaleTexture(-1.1f);
	return 0;
}
int TextureWindow::ResetTexture() {
	g_selection_frame->ResetTexture();
	return 0;
}
int TextureWindow::ChooseTexture() {
	g_choose_tex_window->Show();
	return 0;
}


int TextureWindow::OnSelectionChange(){
	cout << "sm" << endl;

	if(hidden_)
	{
		return -1;
	}

	string new_str;
	int group = g_selection_frame->GetSmoothingGroup();
	if(group == -1)
	{
		new_str = "-";
	} else
	{
		new_str = std::to_string(group);
	}
	sm_gr_edit_field_.SetValue(new_str);

	float tex_vecs[2][4];
	string tex_vecs_text[2][4];

	if(g_selection_frame->GetTexVecs(tex_vecs))
	{
		cout << "u: " << tex_vecs[0][0] << " " << tex_vecs[0][1] << " " << tex_vecs[0][2] << " " << tex_vecs[0][3] << "\n";
		cout << "v: " << tex_vecs[1][0] << " " << tex_vecs[1][1] << " " << tex_vecs[1][2] << " " << tex_vecs[1][3] << "\n";

		for(int i = 0; i < 2; i++)
		{
			for(int j = 0; j < 4; j++)
			{
				tex_vecs_text[i][j] = std::to_string(tex_vecs[i][j]);
				for(int k = tex_vecs_text[i][j].length(); k > 2; k--)
				{
					if(tex_vecs_text[i][j][k] == '0' && tex_vecs_text[i][j][k-1] != '.')
					{
						tex_vecs_text[i][j].erase(k);
					}
				}
			}
		}
	} else
	{
		for(int i = 0; i < 2; i++)
		{
			for(int j = 0; j < 4; j++)
			{
				tex_vecs_text[i][j] = "-";
			}
		}
	}

	tex_vec00_edit_field_.SetValue(tex_vecs_text[0][0]);
	tex_vec01_edit_field_.SetValue(tex_vecs_text[0][1]);
	tex_vec02_edit_field_.SetValue(tex_vecs_text[0][2]);
	tex_vec03_edit_field_.SetValue(tex_vecs_text[0][3]);

	tex_vec10_edit_field_.SetValue(tex_vecs_text[1][0]);
	tex_vec11_edit_field_.SetValue(tex_vecs_text[1][1]);
	tex_vec12_edit_field_.SetValue(tex_vecs_text[1][2]);
	tex_vec13_edit_field_.SetValue(tex_vecs_text[1][3]);

	shared_ptr<GLTexture> tex;
	float angle;
	string id_str, angle_str;
	if(g_selection_frame->GetTexAndAngle(tex, angle))
	{
		id_str = std::to_string(Renderer::GetTextureIndex(tex));
		angle_str = std::to_string(angle);
		for(int k = angle_str.length(); k > 2; k--)
		{
			if(angle_str[k] == '0' && angle_str[k-1] != '.')
			{
				angle_str.erase(k);
			}
		}

	} else
	{
		id_str = "-";
		angle_str = "-";
	}
	tex_id_edit_field_.SetValue(id_str);
	tex_angle_edit_field_.SetValue(angle_str);

	this->SetTopMost();
	ForceWindowUpdate();
	update_needed_ = true;

	//sm_group_edit_.reset(new MyEditBox(new_str, 0.0f, -0.5f, 0.4f, 0.4f, 1.0f, window_size_, FLOATS));
	return 0;
}
int TextureWindow::ApplyTextureChange(string str)
{
	g_selection_frame->SetSmoothingGroup(atoi(str.c_str()));
	return 0;
}

int TextureWindow::ApplyTexVecs(string str)
{
	float tex_vecs[2][4];
	tex_vecs[0][0] = atof(tex_vec00_edit_field_.GetValue().c_str());
	tex_vecs[0][1] = atof(tex_vec01_edit_field_.GetValue().c_str());
	tex_vecs[0][2] = atof(tex_vec02_edit_field_.GetValue().c_str());
	tex_vecs[0][3] = atof(tex_vec03_edit_field_.GetValue().c_str());

	tex_vecs[1][0] = atof(tex_vec10_edit_field_.GetValue().c_str());
	tex_vecs[1][1] = atof(tex_vec11_edit_field_.GetValue().c_str());
	tex_vecs[1][2] = atof(tex_vec12_edit_field_.GetValue().c_str());
	tex_vecs[1][3] = atof(tex_vec13_edit_field_.GetValue().c_str());

	g_selection_frame->SetTexVecs(tex_vecs);
	return 0;
}

int TextureWindow::ApplyTexAngle(string str){
	g_selection_frame->SetTexAngle(atof(str.c_str()));
}

